import datetime
import time


UNIX_EPOCH = datetime.datetime(1970, 1, 1, 0, 0, 0)


MONTHS = ['January',
    'February',
    'March',
    'April',
    'May',
    'June',
    'July',
    'August',
    'September',
    'October',
    'November',
    'December']

SECONDS_PER_DAY = 24 * 60 * 60
MONTHINDEX = dict((x[1].lower(), x[0] + 1) for x in enumerate(MONTHS))


def is_month_name(name):
    return name.lower() in set(x.lower() for x in MONTHS)


def days_in_month(year, month):
    # gets around calendar's annoying week completion

    from calendar import Calendar

    days = list(Calendar().itermonthdays(year, month))
    while days[0] == 0:
        days.pop(0)

    while days[-1] == 0:
        days.pop(-1)

    return days


def parse_datetime_str(s):
    # format: yyyy-mm-dd hh:mm:ss

    datemonthday, hourminutesecond = s.split()
    year, month, day = map(int, datemonthday.split('-'))
    hour, minute, second = hourminutesecond.split(':')
    second, micro = second.split('.')
    hour, minute, second, micro = map(int, (hour, minute, second, micro)) 

    return datetime.datetime(year, month, day, hour, minute, second, micro)


def parse(time):
    # format: 2010-08-28T15:22:29Z

    if time.endswith('Z'):
        time = time[:-1]

    date, time = time.split('T')
    year, month, day = map(int, date.split('-'))
    hour, minute, seconds = map(int, time.split(':'))

    return datetime.datetime(year, month, day, hour, minute, seconds)


def flatten_time_delta(td):
    return (td.days * SECONDS_PER_DAY) + td.seconds


def before_now_in_seconds(dt):
    return flatten_time_delta(datetime.datetime.now() - dt)


def month_name(number):
    return MONTHS[number]


def monthname2digit(name):
    return MONTHINDEX.get(name.lower(), None)


def seconds2datetime(seconds):
    t = time.gmtime(seconds)
    return datetime.datetime(t.tm_year, t.tm_mon, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec)


def seconds2timedelta(seconds):
    return datetime.timedelta(seconds / SECONDS_PER_DAY, seconds % SECONDS_PER_DAY)


def seconds_since_epoch(dt):
    return flatten_time_delta(dt - UNIX_EPOCH)


if __name__ == '__main__':
    print seconds2datetime(1294290000)
    print parse('2010-08-28T15:22:29Z')

    print days_in_month(2011, 5)

    print seconds_since_epoch(datetime.datetime.now())

    d = datetime.datetime.now()
    assert parse_datetime_str(str(d)) == d
